[PATCH 11/24] lib-var-expand: Add "safe" filter to prevent escaping output
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 25 Feb 2026 10:40:22 +0000 (12:40 +0200)
committerNoah Meyerhans <noahm@debian.org>
Tue, 31 Mar 2026 19:07:17 +0000 (15:07 -0400)
For example ldap_base = %{passdb:next_dn | safe} to avoid escaping the DN.

Gbp-Pq: Name CVE-2026-24031-27860-8.patch

src/lib-var-expand/expansion-filter.c
src/lib-var-expand/expansion-program.c
src/lib-var-expand/var-expand-private.h

index 790005786df35a0dab621780b9d802590eceb3e0..93affebc1ddb0dd64debb4e7223316b9789f9a0a 100644 (file)
@@ -1130,6 +1130,14 @@ static int fn_text(const struct var_expand_statement *stmt,
        return 0;
 }
 
+static int fn_safe(const struct var_expand_statement *stmt ATTR_UNUSED,
+                  struct var_expand_state *state,
+                  const char **error_r ATTR_UNUSED)
+{
+       state->transfer_safe = TRUE;
+       return 0;
+}
+
 static const struct var_expand_filter var_expand_builtin_filters[] = {
        { .name = "lookup", .filter = fn_lookup },
        { .name = "literal", .filter = fn_literal },
@@ -1167,6 +1175,7 @@ static const struct var_expand_filter var_expand_builtin_filters[] = {
        { .name = "text", .filter = fn_text },
        { .name = "encrypt", .filter = expansion_filter_encrypt },
        { .name = "decrypt", .filter = expansion_filter_decrypt },
+       { .name = "safe", .filter = fn_safe },
        { .name = NULL }
 };
 
index 5f64b5bda6247d0eb455a9419944399e44309ce6..6a05bc386f03b8aee638d2d83c11554bace1117e 100644 (file)
@@ -140,7 +140,8 @@ int var_expand_program_execute(string_t *dest, const struct var_expand_program *
                if (state.transfer_binary)
                        var_expand_state_set_transfer(&state, binary_to_hex(state.transfer->data, state.transfer->used));
                if (state.transfer_set) {
-                       if (!program->only_literal && params->escape_func != NULL) {
+                       if (!program->only_literal && !state.transfer_safe &&
+                           params->escape_func != NULL) {
                                str_append(state.result,
                                           params->escape_func(str_c(state.transfer),
                                                               params->escape_context));
index 26d30c60bc4b4b776beaec0d9b25c0d1b8f6e58e..ae3aef82b38542c4121d278dfd5edc602d1183c5 100644 (file)
@@ -73,6 +73,7 @@ struct var_expand_state {
        string_t *transfer;
        bool transfer_set:1;
        bool transfer_binary:1;
+       bool transfer_safe:1;
 };
 
 struct var_expand_statement {